package com.db.stockexchange.domain.order;

import java.math.BigDecimal;

import com.db.stockexchange.network.Server.Connection;

public class Order {
//	private static volatile long nextId = 1;
	
	private int clientOrderId;
	private BigDecimal price;
	private int quantity;
	private String symbol;
	private OrderSide orderSide;
	private OrderType orderType;
	private OrderStatus orderStatus = OrderStatus.NEW;

	private int filledQuantity = 0;
	
	private Connection connection;
	private String username;
	
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Connection getConnection() {
		return connection;
	}

	public int getClientOrderId() {
		return clientOrderId;
	}

	public void setConnection(Connection connection) {
		this.connection = connection;
	}

	public Order(int clientOrderId, int quantity, String symbol, OrderSide orderSide) {
		this(clientOrderId, quantity, symbol, orderSide, new BigDecimal(0));
		this.orderType = OrderType.MARKET;
	}

	public Order(int clientOrderId, int quantity, String symbol, OrderSide orderSide, BigDecimal price) {
		if (quantity <= 0)
			// TODO edit message
			throw new IllegalArgumentException("qty must be positive");
		if (price.signum() < 0)
			// TODO edit message
			throw new IllegalArgumentException("price can't be negative");

		this.clientOrderId = clientOrderId;
		this.quantity = quantity;
		this.symbol = symbol;
		this.orderSide = orderSide;
		this.price = price;
		this.orderType = OrderType.LIMIT;
	}

	public void fill(int qtyToFill) {
		if (!(orderStatus == OrderStatus.NEW || orderStatus == OrderStatus.PARTIALLY_FILLED))
			// TODO edit message
			throw new IllegalStateException("illegal order status for fill");

		if (getResidualQuantity() < qtyToFill)
			// TODO edit message
			throw new IllegalArgumentException("fill qty is too big");

		filledQuantity += qtyToFill;
		if (getResidualQuantity() == 0)
			orderStatus = OrderStatus.FILLED;
		else
			orderStatus = OrderStatus.PARTIALLY_FILLED;
	}
	
	public void reject() {
		orderStatus = OrderStatus.REJECTED;
	}

	public OrderStatus getOrderStatus() {
		return orderStatus;
	}

	public BigDecimal getPrice() {
		return price;
	}

	public int getQuantity() {
		return quantity;
	}

	public int getFilledQuantity() {
		return filledQuantity;
	}

	public int getResidualQuantity() {
		return quantity - filledQuantity;
	}

	public String getSymbol() {
		return symbol;
	}

	public OrderSide getSide() {
		return orderSide;
	}

	public OrderType getOrderType() {
		return orderType;
	}

	@Override
	public String toString() {
		if (orderType == OrderType.LIMIT)
			return String.format("[Order %d %s %d %s for %s | %s]",
					clientOrderId, orderSide, quantity, symbol, price, orderStatus);
		else
			return String.format("[Order %d %s %d %s MARKET | %s]",
					clientOrderId, orderSide, quantity, symbol, orderStatus);
	}

}
